package org.sixtynine.stock.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Company;
import org.sixtynine.stock.entity.DailyShareData;
import org.sixtynine.stock.model.FileUploadForm;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.CompanyService;
import org.sixtynine.stock.service.DailyShareDataService;
import org.sixtynine.stock.service.StockPersistentService;
import org.sixtynine.stock.service.file.ExcelProcessorFactory;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.SessionBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan
 * 
 *         this class handle daily share data
 */

@Controller
@SessionAttributes
public class DailyShareController extends PriceDataController {

	@Autowired
	private DailyShareDataService dailyShareDataService;

	@Autowired
	private StockPersistentService stockPersistentService;

	@Autowired
	private CompanyService companyService;

	private static final String BIND_VAL_DAILY_SHARE_DATA = "dailyShareData";

	@RequestMapping(value = "/admin/dailysharedata/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria,
			HttpServletRequest request) {
		return super.search(criteria, request);
	}

	@Override
	protected String getPage() {
		return "/admin/dailysharedata/list";
	}

	@Override
	protected void setPageData(int companyId, Date fromDate, Date toDate,
			String sortByFirst, String sortBySecond, GridPramDTO gridPramDTO,
			ModelAndView modelAndView) {
		Page<DailyShareData> sharePage = dailyShareDataService
				.searchDailyShareData(companyId, fromDate, toDate, null, null,
						gridPramDTO);
		modelAndView.addObject("dailySharePage", sharePage);
	}

	@RequestMapping(value = "/admin/dailysharedata/add")
	public ModelAndView addDailyShareData(HttpServletRequest request) {

		ModelAndView modelAndView = new ModelAndView(getAddPage());

		bindDummyObject(modelAndView);
		bindCompanyList(modelAndView);
		bindFileUpload(modelAndView);

		return modelAndView;

	}

	protected String getExelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_DAILY_SHARE_DATA_LIST;
	}

	@RequestMapping(value = "/admin/dailysharedata/add/file_process")
	public ModelAndView addDailyShareByFile(HttpServletRequest request,
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return addShareByFile(request, uploadFile);
	}

	@RequestMapping(value = "/admin/dailysharedata/add/company_process")
	public ModelAndView processDailyShareDataByCompany(
			HttpServletRequest request,
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return processShareDataByCompany(uploadFile);
	}

	@RequestMapping(value = "/admin/dailysharedata/add/process")
	public ModelAndView addDailyShareData(HttpServletRequest request,
			@Valid @ModelAttribute DailyShareData dailyShareData,
			BindingResult result) {

		ModelAndView modelAndView = null;
		if (dailyShareData.getDate() == null) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "The date cannot be empty, Please enter a correct date.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		if (DateUtil.checkFutureDate(dailyShareData.getDate())) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "You can't add a future date. Please enter a current or past record.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		Criterion dateCriterion = (Restrictions.eq("date",
				dailyShareData.getDate()));
		Criterion cmpCriterion = (Restrictions.eq("company",
				dailyShareData.getCompany()));
		List<BaseEntity> dataList = genericService.findByCriteria(
				DailyShareData.class, dateCriterion, cmpCriterion);
		if (dataList.size() > 0) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "Data already exists for ."
					+ dailyShareData.getDate();
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			loadData(1, -1, dailyShareData.getCompany().getId(), null,
					dailyShareData.getDate(), dailyShareData.getDate(),
					modelAndView, null);
			return modelAndView;
		}

		if (!result.hasErrors()) {
			genericService.saveOrUpdate(dailyShareData);
			modelAndView = new ModelAndView(getPage());

			String message = "Data is successfully inserted.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			loadData(1, -1, dailyShareData.getCompany().getId(), null,
					dailyShareData.getDate(), dailyShareData.getDate(),
					modelAndView, null);
		} else {
			modelAndView = new ModelAndView(getAddPage());
			bindDummyObject(modelAndView);
			bindCompanyList(modelAndView);
			bindFileUpload(modelAndView);
		}

		return modelAndView;

	}

	protected void bindFileUpload(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_FILE_UPLOAD, new FileUploadForm());
	}

	protected void bindDummyObject(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_DAILY_SHARE_DATA, new DailyShareData());
	}

	@RequestMapping(value = "/admin/dailysharedata/list")
	public ModelAndView listOfDailyShareData(
			HttpServletRequest request,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {
		return showList(request, page, totalRecords);
	}

	@RequestMapping(value = "/admin/dailysharedata/edit/{id}", method = RequestMethod.GET)
	public ModelAndView showDailyShareEdit(HttpServletRequest request,
			@PathVariable Integer id) {
		return showEdit(id);
	}

	@RequestMapping(value = "/admin/dailysharedata/edit/{id}", method = RequestMethod.POST)
	public ModelAndView editingDailyShareData(
			@Valid @ModelAttribute("dailyShareData") DailyShareData dailyShareData,
			BindingResult result) {
		return editShareData(dailyShareData, result);
	}

	@RequestMapping(value = "/admin/dailysharedata/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteDailyShareData(@PathVariable Integer id,
			HttpServletRequest request) {
		return deleteShareData(id);
	}

	@RequestMapping(value = "/admin/dailysharedata/delete/selected", method = RequestMethod.POST)
	public ModelAndView deleteSelectedDailyShareData(
			HttpServletRequest request,
			@RequestParam(value = "deleteIds", required = false) Integer[] deleteIds) {
		return deleteSelected(deleteIds);
	}

	@RequestMapping(value = "/admin/dailysharedata/deleteFiltered")
	public ModelAndView deleteFilteredDailyShareData(HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView(getPage());

		SessionBean sBean = SessionBean.getInstance(request);
		LoadingSearchCriteria criteria = (LoadingSearchCriteria) sBean
				.getAttr(SEARCH_CRITERIA);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();
		}

		if (criteria.getCompanyId() == 0) {
			criteria.setCompanyId(-1);
		}

		if (criteria.getCompanyName() != null
				&& !criteria.getCompanyName().isEmpty()) {

			Company company = companyService.findCompany(
					criteria.getCompanyName(), criteria.getCompanyId());

			if (company != null) {
				criteria.setCompanyId(company.getId());
			} else {
				criteria.setCompanyId(-1);
			}
		}

		// delete the selected criteria
		dailyShareDataService.deleteDailyShareData(criteria.getCompanyId(),
				criteria.getFromDate(), criteria.getToDate());

		// reload the page

		String message = "Successfully deleted filted data.";
		modelAndView.addObject(BIND_VAL_MESSAGE, message);

		loadData(1, -1, -1, null, null, null, modelAndView, criteria);

		return modelAndView;
	}

	@Override
	protected Class getBaseClass() {
		return DailyShareData.class;
	}

	@Override
	protected void loadData(Integer page, Integer totalRecords,
			BaseEntity shareData, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		DailyShareData dailyShareData = (DailyShareData) shareData;
		loadData(page, totalRecords, dailyShareData.getCompany().getId(), null,
				dailyShareData.getDate(), dailyShareData.getDate(),
				modelAndView, criteria);
	}

	@Override
	protected String getEditPage() {
		return "/admin/dailysharedata/edit";
	}

	@Override
	protected String getObjBindName() {
		return "dailyShareData";
	}

	@Override
	protected String getAddPage() {
		return "/admin/dailysharedata/add";
	}

	@Override
	protected String getCompanyExcelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_COMPANY_DAILY_SHARE_DATA_LIST;
	}

}
